home *** CD-ROM | disk | FTP | other *** search
/ Precision Software Appli…tions Silver Collection 1 / Precision Software Applications Silver Collection Volume One (PSM) (1993).iso / tutor / s3bas11.arj / S3DATE.BAS < prev    next >
BASIC Source File  |  1993-04-02  |  7KB  |  213 lines

  1. '  S3 Demo of calling interrupts using Microsoft's
  2. '  Visual BASIC for DOS.
  3. '
  4. '  Copyright April 1, 1993  George Spafford
  5. '
  6. '  This program is for AT BIOS type machines ONLY!
  7. '  It reads the date from the Real Time Clock chip
  8. '  using Interrupt 1AH and function 04H.
  9. '
  10. '-------------------------------------------------
  11.  
  12. 'To use the in-line assembly calls, you must start
  13. 'your BASIC compiler with its specified library that
  14. 'contains support for the additional calls.
  15. 'For VBDOS:         VBDOS  S3DATE /L VBDOS
  16. '    QB 4.5:        QB S3DATE /L QB
  17. '
  18. 'So on and so forth.  If you do not, then you will get
  19. 'an error message stating that the function can not be
  20. 'found when the program attempts to execute the
  21. 'CALL INTERRUPT subroutine.
  22.  
  23. TYPE RegType
  24.      AX    AS INTEGER
  25.      bx    AS INTEGER
  26.      CX    AS INTEGER
  27.      DX    AS INTEGER
  28.      bp    AS INTEGER
  29.      si    AS INTEGER
  30.      di    AS INTEGER
  31.      Flags AS INTEGER
  32. END TYPE
  33.  
  34. 'The ?X registers are all 16 bit registers.  Each
  35. '16 bit register can be split into two 8 bit registers
  36. 'titled ?H for high and ?L for low.  For example, AX
  37. 'is comprised of AH and AL.  BASIC operates at the
  38. '16 bit register level.
  39.  
  40. DECLARE SUB INTERRUPT (IntNum AS INTEGER, InReg AS RegType, OutReg AS RegType)
  41.  
  42. DIM InReg AS RegType
  43. DIM OutReg AS RegType
  44.  
  45. DEFINT A-Z      'by default our variables will be
  46.                 'integers.
  47.  
  48. 'This example uses INT 1AH function 04H to read the
  49. 'Real Time Clock (RTC) date.  It also serves as a good
  50. 'example on how to read and set high/low values in
  51. 'the 16 bit registers.
  52.  
  53. 'One note on variable notation, in BASIC, &H signifies
  54. 'a hexadecimal value.  This greatly simplifies making
  55. 'system calls since it saves you from converting to
  56. 'decimal.
  57.  
  58. CLS
  59. PRINT "S3 Demo of reading the RTC Date using interrupts"
  60.  
  61.  
  62. 'CALL THE INTERRUPT
  63.  
  64.     IntNum = &H1A            'int 1AH
  65.     InReg.AX = &H4 * 256     'loads &H4 into AH
  66.                              'this is the function value
  67.                              'this will destroy AL, multiplying
  68.                              'by 256 shifts the 4H value to the
  69.                              'high 8 bit register - remember,
  70.                              'an 8-bit reg is 128, two is 256.
  71.  
  72.     CALL INTERRUPT(IntNum, InReg, OutReg)
  73.  
  74.     'The next segment is an error trap.  If the carry
  75.     'flag, which is in the flag register as bit 0, tests
  76.     'true, then the RTC is reporting that there is a
  77.     'problem.  The use of bits will be discussed later.
  78.  
  79.     IF OutReg.Flags AND 1 THEN
  80.        PRINT "ERROR:  RTC reports a dead battery."
  81.        END
  82.     END IF
  83.                                         
  84.     'Just a note about the below code segment,
  85.     'you must check for long integers, if the
  86.     'register were to contain a negative number,
  87.     'you must add 65536 to it to get the value.
  88.     'Essentially you are converting from a word
  89.     'to a Dword since QB interprets the highest bit
  90.     'as a indicator of the sign of a number.  A
  91.     'Dword is a long integer with a value up to
  92.     '2^31.  In a large program, you should make
  93.     'the conversion routine a function.
  94.  
  95.     IF OutReg.CX < 0 THEN
  96.        DWord& = OutReg.CX + 65536
  97.     ELSE
  98.        DWord& = OutReg.CX
  99.     END IF
  100.     CH = DWord& \ 256     'get CH from CX
  101.     CL = DWord& AND &HFF  'get CL from CX
  102.  
  103.     IF OutReg.DX < 0 THEN
  104.        DWord& = OutReg.DX + 65536
  105.     ELSE
  106.        DWord& = OutReg.DX
  107.     END IF
  108.     DH = DWord& \ 256     'get DH from DX
  109.     DL = DWord& AND &HFF  'get DL from DX
  110.     
  111.  
  112.     'The next part is due to the Motorola MC-146818
  113.     'Real Time Clock Processor which is used in AT's.
  114.     'It returns the answer as a Binary Coded Decimal
  115.     'also known as a BCD.  A BCD has its answer as
  116.     'two 4-bit values.  Thus, our 8-bit registers must
  117.     'first be evaluated for the low value (V1) and the
  118.     'high value (V2).  This bit wise evaluation is
  119.     'performed by using the AND operator.  For a
  120.     'bit to be in position 1, it will test true with
  121.     'the value of one since the bit interpretation of
  122.     '1 is 00000001.  Thus, any number with a bit in
  123.     'the 1 position will test true under the AND
  124.     'function.  This is where bit values come into
  125.     'play.  I will explain this better after the
  126.     'following code segment.
  127.  
  128. 'INTERPRET THE DATA
  129.  
  130.     V1 = 0: V2 = 0
  131.     IF CH AND 1 THEN V1 = 1         'Low:   bit 1
  132.     IF CH AND 2 THEN V1 = V1 + 2    '           2
  133.     IF CH AND 4 THEN V1 = V1 + 4    '           3
  134.     IF CH AND 8 THEN V1 = V1 + 8    '           4
  135.  
  136.     IF CH AND 16 THEN V2 = 1        'High:  bit 1
  137.     IF CH AND 32 THEN V2 = V2 + 2   '           2
  138.     IF CH AND 64 THEN V2 = V2 + 4   '           3
  139.     IF CH AND 128 THEN V2 = V2 + 8  '           4
  140.  
  141.     'Okay, all data can be represented as bits.  For
  142.     'a single 8 bit byte, there are 8 possible
  143.     'positions.
  144.     'binary:                     Decimal:
  145.     '00000001    =    2^0    =     1
  146.     '00000010    =    2^1    =     2
  147.     '00000100    =    2^2    =     4
  148.     '00001000    =    2^3    =     8
  149.     '00010000    =    2^4    =    16
  150.     '00100000    =    2^5    =    32
  151.     '01000000    =    2^6    =    64
  152.     '10000000    =    2^7    =   128
  153.     'The AND operator allows you to test each bit
  154.     'position using the decimal value.
  155.     
  156.     Cent$ = LTRIM$(STR$(V2)) + LTRIM$(STR$(V1))
  157.  
  158.     V1 = 0: V2 = 0
  159.     IF CL AND 1 THEN V1 = 1         'Low:  bit 1
  160.     IF CL AND 2 THEN V1 = V1 + 2    '          2
  161.     IF CL AND 4 THEN V1 = V1 + 4    '          3
  162.     IF CL AND 8 THEN V1 = V1 + 8    '          4
  163.     IF CL AND 16 THEN V2 = 1        'High: bit 1
  164.     IF CL AND 32 THEN V2 = V2 + 2   '          2
  165.     IF CL AND 64 THEN V2 = V2 + 4   '          3
  166.     IF CL AND 128 THEN V2 = V2 + 8  '          4
  167.  
  168.     Year$ = LTRIM$(STR$(V2)) + LTRIM$(STR$(V1))
  169.  
  170.     V1 = 0: V2 = 0
  171.     IF DH AND 1 THEN V1 = 1         'Low:  bit 1
  172.     IF DH AND 2 THEN V1 = V1 + 2    '          2
  173.     IF DH AND 4 THEN V1 = V1 + 4    '          3
  174.     IF DH AND 8 THEN V1 = V1 + 8    '          4
  175.     IF DH AND 16 THEN V2 = 1        'High: bit 1
  176.     IF DH AND 32 THEN V2 = V2 + 2   '          2
  177.     IF DH AND 64 THEN V2 = V2 + 4   '          3
  178.     IF DH AND 128 THEN V2 = V2 + 8  '          4
  179.   
  180.     Month$ = LTRIM$(STR$(V2)) + LTRIM$(STR$(V1))
  181.  
  182.     'To use less code, you could use a subroutine
  183.     'or two functions to get the V1 and V2 values.
  184.     'I opted for laying them out in a top-to-bottom
  185.     'manner to allow for easy reading.
  186.     'Note, you must clear V1 and V2 before you
  187.     'test the bits or else you may get an erronous
  188.     'figure if one of the 4-bit registers is 0.
  189.     
  190.     V1 = 0: V2 = 0
  191.     IF DL AND 1 THEN V1 = 1         'Low:  bit 1
  192.     IF DL AND 2 THEN V1 = V1 + 2    '          2
  193.     IF DL AND 4 THEN V1 = V1 + 4    '          3
  194.     IF DL AND 8 THEN V1 = V1 + 8    '          4
  195.     IF DL AND 16 THEN V2 = 1        'High: bit 1
  196.     IF DL AND 32 THEN V2 = V2 + 2   '          2
  197.     IF DL AND 64 THEN V2 = V2 + 4   '          3
  198.     IF DL AND 128 THEN V2 = V2 + 8  '          4
  199.  
  200.     Day$ = LTRIM$(STR$(V2)) + LTRIM$(STR$(V1))
  201.  
  202.     LOCATE 4, 1
  203.     PRINT "Century.....:  "; Cent$
  204.     PRINT "Year........:  "; Year$
  205.     PRINT "Month.......:  "; Month$
  206.     PRINT "Day.........:  "; Day$
  207.  
  208.     'So there you have it.  Heck, if you feel lazy,
  209.     'then just use the DATE$ function ;-)
  210.     
  211. END
  212.  
  213.